package com.runa.rccprotocol.analysis.lanjier;

import com.runa.protocol.analysis.MetaBufferAnalysis;
import com.runa.protocol.analysis.ShellBufferAnalysis;
import com.runa.protocol.dto.DtuReport;
import com.runa.protocol.dto.IInterData;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.util.ByteUtil;
import com.runa.protocol.util.Crc32TJSW;
import com.runa.rccprotocol.analysis.EnAnalysis;
import com.runa.rccprotocol.analysis.RunaDeviceAnalysis;
import com.runa.rccprotocol.analysis.lichuang.LiChuangEquDataAnalysis;
import com.runa.rccprotocol.analysis.zhongrun.ZhongRunMeterDataAnalysis;
import com.runa.rccprotocol.dto.lanjier.LanJiErReportAck;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 兰吉尔集中器 透传
 * 传输协议 LJE_FMU
 *
 * @author diandian
 * @Date 2022/4/28 13:17
 */
public class LanJiErFmuAnalysis extends ShellBufferAnalysis<byte[]> {

    public LanJiErFmuAnalysis() {
        super(null, 350);
        //兰吉尔二级寻址
        this.analysisMap.put(0xD1, enAnalysis);
        this.analysisMap.put(0x10, enAnalysis);
        //兰吉尔响应数据
        this.analysisMap.put(0xF7, enAnalysis);
        //中润响应数据
        this.analysisMap.put(0x4E, zhongRunMeterDataAnalysis);
        //瑞纳响应数据
        this.analysisMap.put(0x57, runaDeviceAnalysis);
        //力创响应数据
        this.analysisMap.put(0x4C, liChuangEquDataAnalysis);
    }

    private DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");

    private Crc32TJSW tjsw = new Crc32TJSW();


    private EnAnalysis enAnalysis = new EnAnalysis();
    private ZhongRunMeterDataAnalysis zhongRunMeterDataAnalysis = new ZhongRunMeterDataAnalysis();
    private RunaDeviceAnalysis runaDeviceAnalysis = new RunaDeviceAnalysis();
    private LiChuangEquDataAnalysis liChuangEquDataAnalysis = new LiChuangEquDataAnalysis();
    private Map<Integer, MetaBufferAnalysis> analysisMap = new HashMap<>();

    @Override
    public int fill(byte[] data, int length,String n) {
        this.interData = null;
        int begin = -1;
        for (int i = 0; i < length; i++) {
            if ((data[i] & 0xff) == 0x49) {
                //长度不够
                if (i + 4 > length) {
                    return -1;
                }
                int beginData = ByteUtil.byteToInt(data, i, ByteOrder.ABCD);
                //报文头
                if (0x494F5440 == beginData) {
                    begin = i;
                }
            }
        }
        //没有找到报文头
        if (begin == -1) {
            return 0;
        }
        //长度不够
        if (begin + 15 > length) {
            return -1;
        }
        //数据域长度
        int dataLen = data[begin + 14] & 0xff;
        if (length < begin + 21 + dataLen) {
            //字节长度不够，重新续字节
            return -1;
        }
        //校验和
        byte[] crc32 = this.tjsw.getBytesFlip(data, begin + 4, length - 4 - 6);
        boolean check = ByteUtil.byteArrayEqual(crc32, 0, data, length - 6, 4);
        if (!check) {
            return 0;
        }

        //截取真实的数据报文
        System.arraycopy(data, begin + 15, this.buffer, 0, dataLen);

        int index = begin;
        index += 4;
        int fmuDataLen = data[++index] & 0xff;
        int result = -1;

        //消息类型
        int dataType = data[begin + 11] & 0xff;
        if (dataType == 0x01 || dataType == 0x03) {
            result = registerAndHeat(data, length, index, begin, dataLen);
        } else if (dataType == 0xD2) {
            //通过集中器封装的数据长度，来查找具体使用的数据协议
            MetaBufferAnalysis dataAnalysis = this.analysisMap.get(fmuDataLen);
            if (dataAnalysis == null) return 0;
            result = dataAnalysis.fill(this.buffer, dataLen,netEquNo);
            interData = dataAnalysis.gain();
        }
        return result;
    }

    private int registerAndHeat(byte[] data, int length, int index, int begin, int dataLen) {
        //判断结束报文是否合法
        if (!"255E".equals(ByteUtil.byteToHexString(data, begin + 26, 2))) {
            return 0;
        }
        int dataType = data[begin + 11] & 0xff;

        //跳过计数字节
        ++index;
        //编号
        ++index;
        this.netEquNo = ByteUtil.byteToHexString(data, index, 4);

        String dateStr = this.format.format(new Date());

        DtuReport dtuReport = new DtuReport(netEquNo);
        //构建注册响应报文
        if (dataType == 0x01) {
            dtuReport.setMustAck(true);
            dtuReport.setAck(new LanJiErReportAck(netEquNo, 1));
            this.interData = dtuReport;
        } else if (dataType == 0x03) {//心跳
            dtuReport.setMustAck(true);
            dtuReport.setAck(new LanJiErReportAck(netEquNo, 2));
            this.interData = dtuReport;
        }
        return length - (begin + 28);
    }

    @Override
    public IInterData gain() {
        return this.interData;
    }

    public static void main(String[] args) {
//        String s = "00 00 00 49 4F 54 40 00 F7 72 10 46 04 94 D2 A2 00 E8 68 E2 E2 68 08 00 72 49 14 20 67 A7 32 07 04 00 00 00 00 09 74 04 09 70 08 0C 06 69 54 04 00 0C 14 39 14 45 00 0B 2D 00 00 00 0B 3B 00 00 00 0B 5A 81 01 00 0B 5E 73 01 00 0B 62 07 00 00 0C 78 49 14 20 67 89 10 71 07 3C 22 62 31 00 00 0C 22 32 26 08 00 0C 26 71 93 00 00 8C 90 10 06 71 00 00 00 9B 10 2D 64 02 00 9B 10 3B 68 07 00 9B 10 5A 55 08 00 9B 10 5E 64 04 00 94 10 AD 6F 2D 04 BC 1C 94 10 BB 6F 25 04 CA 1B 94 10 DA 6F 3A 01 C7 12 94 10 DE 6F 30 02 C7 12 4C 06 69 54 04 00 4C 14 39 14 45 00 7C 22 62 31 00 00 4C 26 71 93 00 00 CC 90 10 06 71 00 00 00 DB 10 2D 64 02 00 DB 10 3B 68 07 00 DB 10 5A 55 08 00 DB 10 5E 64 04 00 84 8F 0F 6D 00 00 E1 F1 04 6D 0D 17 D8 24 1F 11 07 00 77 01 EE 16 3F 2E 48 83 25 5E"
//                .replace(" ", "");
//        String lichuang = "49 4F 54 40 00 4C B9 10 34 02 48 D2 A2 00 3D FE FE 68 20 04 04 66 30 00 59 42 81 2E 90 1F 00 05 08 03 50 02 05 08 03 50 02 17 00 00 00 00 35 00 00 00 00 2C 07 11 87 00 80 18 00 77 18 00 19 36 01 27 27 19 05 05 22 20 00 BD E1 16 9C EF 92 FF 25 5E"
//                .replace(" ", "");
//        String ruina = "49 4F 54 40 00 57 5F 10 46 04 94 D2 A2 00 48 FE FE FE FE FE FE FE FE FE FE FE FE FE 68 25 84 15 80 21 00 4D 22 81 2E 1F 90 00 00 00 00 00 05 48 05 00 00 05 00 00 00 00 17 00 00 00 00 35 26 00 00 00 2C 98 19 00 63 19 00 85 66 00 38 21 00 05 05 22 20 00 80 C6 16 BE 69 1C 09 25 5E"
//                .replace(" ", "");
//
//        String registry = "49 4F 54 40 00 16 E9 10 46 04 94 01 02 00 07 20 22 04 28 11 02 26 25 63 DF D6 25 5E".replace(" ", "");

        LanJiErFmuAnalysis analysis = new LanJiErFmuAnalysis();
//        byte[] bytes = ByteUtil.hexStringToByte("494F544000104C10460524D2A20001E5C921C4C6255E");
//        byte[] bytes = ByteUtil.hexStringToByte("494F54400010E810460454D2A2000100FC97DB50255E");
        byte[] bytes = ByteUtil.hexStringToByte("494F544000F76E10460525D2A200E868E2E26808007262906866A7320704020000000974040970080C06105802000C14454351000B2D0000000B3B0100F00B5A3202000B5E3202000B620000000C7862906866891071073C22522700000C22676909000C26360201008C901006000000009B102D6700009B103B2010009B105A0505009B105E3804009410AD6F1E06892B9410BB6F071088249410DA6F230A7E189410DE6F0B03FB194C06730702004C14168846007C22522700004C2613780000CC90100600000000DB102D670000DB103B201000DB105A050500DB105E380400848F0F6D0000E1F1046D1510D5290F0907007601DA160F91F223255E");
        analysis.fill(bytes, bytes.length,"");
        System.out.println(analysis.netEquNo);
//
//        String ss = "FE FE FE FE FE FE FE FE FE FE FE FE FE 68 25 94 31 80 21 00 4D 22 81 2E 1F 90 00 00 00 00 00 05 74 72 13 01 05 00 00 00 00 17 00 00 00 00 35 63 72 13 00 2C 08 18 00 67 17 00 30 65 00 30 00 11 28 04 22 20 00 00 06 16"
//                .replace(" ", "");
//        byte[] bytes1 = ByteUtil.hexStringToByte(ss);
//        byte[] tett = newComm byte[72];
//        System.arraycopy(bytes1, 0, tett, 0, 72);
//        System.out.println(ByteUtil.byteToHexString(tett));
//
//        String format = analysis.format.format(newComm Date());
//        byte[] test = newComm byte[7];
//        ByteUtil.tenstringToBcd(test, format, 0, true);
//        System.out.println(ByteUtil.byteToHexString(test));
    }
}